package com.hujing.springsource.a39;

import org.springframework.boot.ConfigurableBootstrapContext;
import org.springframework.boot.DefaultBootstrapContext;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.support.SpringFactoriesLoader;

import java.lang.reflect.Constructor;
import java.util.List;

public class A39_2 {

    public static void main(String[] args) throws Exception {
        SpringApplication app = new SpringApplication();
        //添加app 监听器
        app.addListeners(event -> System.out.println(event.getClass()));

        //获取事件发送器
        List<String> names = SpringFactoriesLoader.loadFactoryNames(SpringApplicationRunListener.class, A39_2.class.getClassLoader());
        for (String name : names) {
            System.out.println(name);
            //创建SpringApplicationRunListener对象
            Class<?> clazz = Class.forName(name);
            Constructor constructor = clazz.getConstructor(SpringApplication.class, String[].class);
            SpringApplicationRunListener publisher = (SpringApplicationRunListener) constructor.newInstance(app,args);

            ConfigurableBootstrapContext bootstrapContext = new DefaultBootstrapContext();
            GenericApplicationContext context = new GenericApplicationContext();
            //发布事件
            publisher.starting(bootstrapContext); // springboot 开始启动
            publisher.environmentPrepared(bootstrapContext,new StandardEnvironment());// 环境信息准备完毕
            publisher.contextPrepared(context);// 在spring容器创建，并调用初始化器之后，发送该事件
            publisher.contextLoaded(context);//所有的bean definition加载完成
            context.refresh();
            publisher.started(context);//spring容器启动完成（refresh()方法调用完成）
            publisher.running(context);// springboot 启动完成

            publisher.failed(context,new Exception("启动失败"));// 启动失败

        }
    }
}
